package com.uyayo.framework.captcha.util;

import com.uyayo.framework.captcha.constants.CaptchaConstants;
import com.uyayo.framework.captcha.exception.CaptchaException;
import com.uyayo.framework.captcha.exception.CaptchaTimeOutException;

/**
 * 验证码工具类
 * @author hfj
 * @date 2018/10/20
 */
public class CaptchaUtils {

    /**
     * 验证码校验
     * 默认验证码超时时间 10 分钟
     *
     * @param captcha           验证码
     * @param exitCodeObject    session中保存的验证码
     * @param captchaTimeObject 验证码记录的时间
     * @throws CaptchaTimeOutException 验证码超时
     * @throws CaptchaException        验证码错误
     */
    public static void verifyCaptcha(String captcha, Object exitCodeObject, Object captchaTimeObject) throws CaptchaException {
        verifyCaptcha(captcha, exitCodeObject, captchaTimeObject, CaptchaConstants.CAPTCHA_TIMEOUT);
    }

    /**
     * 验证码校验
     * 默认验证码超时时间 10 分钟
     *
     * @param object            对象
     * @param exitObject        session中保存的对象
     * @param captcha           验证码
     * @param exitCaptcha       session中保存的验证码
     * @param captchaTimeObject 验证码记录的时间
     * @throws CaptchaTimeOutException 验证码超时
     * @throws CaptchaException        验证码错误
     */
    public static void verifyObjectCaptcha(String object, Object exitObject, String captcha, Object exitCaptcha, Object captchaTimeObject) throws CaptchaException {
        verifyObjectCaptcha(object, exitObject, captcha, exitCaptcha, captchaTimeObject, CaptchaConstants.CAPTCHA_TIMEOUT);
    }

    /**
     * 验证码校验
     * 默认验证码超时时间 10 分钟
     *
     * @param captcha           验证码
     * @param exitCodeObject    session中保存的验证码
     * @param captchaTimeObject 验证码记录的时间
     * @param timeOut           验证码超时时间 毫秒
     * @throws CaptchaTimeOutException 验证码超时
     * @throws CaptchaException        验证码错误
     */
    public static void verifyCaptcha(String captcha, Object exitCodeObject, Object captchaTimeObject, long timeOut) throws CaptchaException {
        if (null == exitCodeObject || null == captchaTimeObject) {
            throw new CaptchaException("Captcha is null");
        }
        String exitCode = (String) exitCodeObject;
        long captchaTime = (Long) captchaTimeObject;
        if (System.currentTimeMillis() - captchaTime > timeOut) {
            throw new CaptchaTimeOutException("captcha timeout");
        }
        if (!exitCode.equalsIgnoreCase(captcha)) {
            throw new CaptchaException("captcha exitCode error");
        }
    }


    /**
     * 验证码校验
     * 默认验证码超时时间 10 分钟
     *
     * @param object            对象
     * @param exitObject        session中保存的对象
     * @param captcha           验证码
     * @param exitCaptcha       session中保存的验证码
     * @param captchaTimeObject 验证码记录的时间
     * @param timeOut           验证码超时时间 毫秒
     * @throws CaptchaTimeOutException 验证码超时
     * @throws CaptchaException        验证码错误
     */
    public static void verifyObjectCaptcha(String object, Object exitObject, String captcha, Object exitCaptcha, Object captchaTimeObject, long timeOut) throws CaptchaException {
        if (null == exitObject || null == exitCaptcha || null == captchaTimeObject) {
            throw new CaptchaException("Captcha is null");
        }
        String exitObjectStr = String.valueOf(exitObject);
        long captchaTime = (Long) captchaTimeObject;
        if (System.currentTimeMillis() - captchaTime > timeOut) {
            throw new CaptchaTimeOutException("captcha timeout");
        }
        if (!exitObjectStr.equalsIgnoreCase(object)) {
            throw new CaptchaException("captcha exitCode error");
        }
        String exitCaptchaStr = String.valueOf(exitCaptcha);

        if (!exitCaptchaStr.equalsIgnoreCase(captcha)) {
            throw new CaptchaException("captcha exitCode error");
        }
    }




    public static void verifySessionCode(String code, String sessionCode, String sessionTimeout, String principal) throws CaptchaException {
        verifySessionCode(code, sessionCode, sessionTimeout, principal, CaptchaConstants.CAPTCHA_TIMEOUT);

    }

    /**
     * 验证码检查
     * 为保证验证主体安全
     * 验证码value和timeout必须符合 验证码_主体,时间_主体的格式
     * 例如
     * 123456_ag12345
     * check时会比对主体是否一致
     *
     * @param code
     * @param sessionCode
     * @param sessionTimeout
     * @param principal
     * @throws CaptchaException
     */
    public static void verifySessionCode(String code, String sessionCode, String sessionTimeout, String principal, long timeout) throws CaptchaException {
        if (code == null) {
            throw new CaptchaException("验证码不能为空!");
        }
        if (sessionCode == null || sessionTimeout ==null) {
            throw new CaptchaException("验证码不存在!");
        }
        if (principal == null) {
            throw new CaptchaException("验证信息不能为空!");
        }
        //session中每个key最大的长度
        int maxLength = 2;
        String[] codeArray = sessionCode.split(CaptchaConstants.UNDER_LINE);
        String[] timeoutArray = sessionTimeout.split(CaptchaConstants.UNDER_LINE);
        if (codeArray.length != maxLength || timeoutArray.length != maxLength) {
            throw new CaptchaException("验证信息异常!");
        }
        if (!principal.equalsIgnoreCase(codeArray[1]) || !principal.equalsIgnoreCase(timeoutArray[1])) {
            //验证主体对应不上
            throw new CaptchaException("验证主体对应错误!");
        }
        if (!code.equalsIgnoreCase(codeArray[0])) {
            throw new CaptchaException("验证码错误!");
        }
        if (System.currentTimeMillis() - Long.parseLong(timeoutArray[0]) > timeout) {
            throw new CaptchaTimeOutException("验证码已超时!");
        }

    }
}
